#define _CRT_SECURE_NO_WARNINGS  1
#include"String.h"

namespace Solution
{


	ostream& operator<<(ostream& out, const string& s)
	{
		out << s.c_str();
		return out;
	}
	istream& operator>>(istream& in, string& s)
	{
		s.clear();
		char buff[256] = "\0";
		int i = 0;
		char c = in.get();
		while (c != '\n' && c != ' ')
		{
			buff[i++] = c;
			if (i==254)
			{
				s += buff;
				i = 0;
			}
			c = in.get(); 
		}
		if (i != 0)
			s += buff;


		return in;

	}

	void string::reserve(size_t n)
	{
		if (n > _capacity)
		{
			char* tmp = new char[n+1];
			strcpy(tmp, _arr);
			delete[]_arr;
			_arr = tmp;
			_capacity = n;
		}
	}

	void string::append(const char c)
	{
		if (_size == _capacity)
		{
			reserve(_capacity ? 2 * _capacity : 4);
		}
		_arr[_size++] = c;
		_arr[_size] = '\0';
	}
	void string::append(const string& s)
	{
		*this += s;
	}

	string& string::operator+=(const string& s)
	{
		size_t len = strlen(s.c_str());
		if (_size + len > _capacity)
		{
			reserve(_size+len+4);
		}
		strcpy(_arr + _size, s.c_str());
		_size = _size + len;
		return *this;

	}

	string& string::operator+=(char c)
	{
		append(c);
		return *this;
	}

	
	void string::push_back(const char c)
	{
		append(c);
	}
	string& string::insert(size_t pos, const string& str)
	{
		assert(pos < _size);
		size_t len = strlen(str.c_str());

		if (len + _size > _capacity)
		{
			reserve(len + _size + 4);
		}

		size_t end = _size + len;
		while (end > pos + len - 1)
		{
			_arr[end] = _arr[end - len];
			end--;
		}
		for (size_t i = pos; i < len + pos; i++)
		{
			_arr[i] = str.c_str()[i - pos];
		}
		_size = len + _size;
		return *this;
	}

	string& string::insert(size_t pos, const char c)
	{
		assert(pos < _size);

		if (_size == _capacity)
		{
			reserve(_capacity ? 2 * _capacity : 4);
		}

		size_t end = _size;
		while (end >= pos)
		{
			_arr[end+1] = _arr[end];
			end--;
		}

		_size++;
		_arr[pos] = c;

		return *this;
	}
	
	
	string& string::erase(size_t pos, size_t len)
	{
		assert(pos < _size);
		if (len + pos > _size - 1)
		{
			_arr[pos] = '\0';
		}

		size_t end = pos + len;
		while (end<_size)
		{
			_arr[end - len] = _arr[end];
			end++;
		}
		return *this;
	}

	string string::substr(size_t pos, size_t len) const
	{
		/*char* arr = new char[len + 1];
		strncpy(arr, _arr,len);
		arr[len] = '\0';
		string tmp(arr);
		delete[]arr;
		return tmp;*/

		if (len > _size - pos)
		{
			len = _size - pos;
		};
		string tmp;
		tmp.reserve(len);
		for (size_t i = 0; i < len; i++)
		{
			tmp += _arr[i + pos];
		}

		return tmp;
	}
	
}